package com.ygqh.baby.service.impl;

import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.HttpClientException;
import com.ygqh.baby.ao.Message;
import com.ygqh.baby.exception.YgException;
import com.ygqh.baby.redis.RedisDao;
import com.ygqh.baby.service.WxMpAuthorityService;
import com.ygqh.baby.service.WxMpUserActionService;
import com.ygqh.baby.service.wechat.api.UserActionApi;
import com.ygqh.baby.service.wechat.model.Action;
import com.ygqh.baby.service.wechat.model.Action.ActionType;
import com.ygqh.baby.service.wechat.model.Actions;
import com.ygqh.baby.service.wechat.model.UserActionReport;
import com.ygqh.baby.service.wechat.model.UserActionReport.Aggregation;
import com.ygqh.baby.service.wechat.model.UserActionReport.TimeGranularity;
import com.ygqh.baby.service.wechat.model.UserActionSet;
import com.ygqh.baby.service.wechat.model.UserActionSet.Type;
import com.ygqh.baby.utils.DBHelper;
import com.ygqh.baby.utils.DateConvertUtils;

@Service
public class WxMpUserActionServiceImpl implements WxMpUserActionService {

	@Autowired
	private RedisDao redisDao;
	@Autowired
	private WxMpAuthorityService WxMpAuthorityService;

	private static final String USER_ACTION_SET_ID = "user_action_set_id_%s";

	@Override
	public Message addUserActionSets(UserActionSet userActionSet) throws WeixinException, HttpClientException {
		UserActionApi api = new UserActionApi(WxMpAuthorityService.findTokenHolder());
		JSONObject jsonbject = api.addUserActionSets(userActionSet);
		Integer code = jsonbject == null ? -1 : jsonbject.getInteger("code");
		String id = null;
		Type type = userActionSet.getType();
		if (code == 0) {
			JSONObject data = jsonbject.getJSONObject("data");
			id = redisDao.set(String.format(USER_ACTION_SET_ID, type.name()), data.getString("user_action_set_id"), 0);
		} else if (jsonbject.getInteger("errcode").compareTo(900351000) == 0) {
			String msg = jsonbject.getString("errmsg");
			id = redisDao.set(String.format(USER_ACTION_SET_ID, type.name()), msg.substring(msg.lastIndexOf(":")).trim(), 0);
		}
		if (StringUtils.isBlank(id)) {
			throw new WeixinException(jsonbject.getString("errmsg"));
		}
		return Message.success(id);
	}

	@Override
	public Message findUserActionSets(String userActionSetId) throws HttpClientException, WeixinException {
		if (StringUtils.isBlank(userActionSetId)) {
			throw new YgException("用户行为源id不能为空");
		}
		UserActionApi api = new UserActionApi(WxMpAuthorityService.findTokenHolder());
		JSONObject jsonObject = api.getUserActionSets(userActionSetId);
		Integer code = jsonObject == null ? -1 : jsonObject.getInteger("errcode");
		if (code != 0) {
			throw new WeixinException(jsonObject.getString("errmsg"));
		}
		JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("list");
		List<UserActionSet> list = JSONArray.parseArray(jsonArray.toJSONString(), UserActionSet.class);
		return Message.success(list);
	}

	@Override
	public Message userActions(String clickId, String currentUrl, ActionType actionType, BigDecimal totalPrice, Type type, Long userId)
			throws WeixinException, HttpClientException, SQLException {
		type = type == null ? Type.WEB : type;
		String userActionSetId = userActionSetId(type);
		if (StringUtils.isBlank(userActionSetId)) {
			throw new WeixinException("获取用户行为源id异常，请稍后重试");
		}
		UserActionApi api = new UserActionApi(WxMpAuthorityService.findTokenHolder());
		Actions Actions = new Actions();
		Action action = new Action();
		action.setUserActionSetId(userActionSetId);
		action.setUrl(StringUtils.isNotBlank(currentUrl) ? currentUrl : "http://m.yiigoo.com");
		Date date = new Date();
		action.setActionTime((int) (date.getTime() / 1000));
		action.setActionType(actionType == null ? ActionType.RESERVATION : actionType);
		action.setTrace(clickId);
		if (totalPrice != null) {
			int value = (int) (totalPrice.doubleValue() * 100);
			action.setActionParam(value);
		}
		Actions.addAction(action);
		JSONObject jsonbject = api.addUserActions(Actions);
		Integer code = jsonbject == null ? -1 : jsonbject.getInteger("errcode");
		if (code != 0) {
			throw new WeixinException(jsonbject.getString("errmsg"));
		}
		// 记录到数据库
		return addToDb(userActionSetId, clickId, currentUrl, actionType, totalPrice, type, date, userId);
	}

	private Message addToDb(String userActionSetId, String clickId, String currentUrl, ActionType actionType, BigDecimal totalPrice, Type type, Date date,
			Long userId) throws SQLException {
		StringBuffer sql = new StringBuffer();
		sql.append("INSERT INTO wx_user_action_report (user_id, user_action_set_id, click_id, action_type, action_time, `type`, order_price, url) VALUE (")
			.append(userId == null ? "NULL" : userId).append(", ")
			.append(userActionSetId).append(", ")
			.append("'").append(clickId).append("'").append(", ")
			.append("'").append(actionType.name()).append("'").append(", ")
			.append("'").append(DateConvertUtils.formatDateTime(date)).append("'").append(", ")
			.append("'").append(type.name()).append("'").append(", ")
			.append(totalPrice == null ? "0.00" : totalPrice.toString()).append(", ")
			.append(StringUtils.isBlank(currentUrl) ? "NULL" : "'" + currentUrl + "'")
			.append(")");
		DBHelper db = new DBHelper();
		PreparedStatement prepareStatement = db.conn.prepareStatement(sql.toString());
		int row = prepareStatement.executeUpdate();
		if (row == 0) {
			throw new YgException("上报成功，存入数据库异常");
		}
		prepareStatement.close();
		db.close();
		return Message.success(1);
	}

	private String userActionSetId(Type type) throws WeixinException, HttpClientException {
		String userActionSetId = redisDao.get(String.format(USER_ACTION_SET_ID, type.name()));
		if (StringUtils.isNotBlank(userActionSetId)) {
			return userActionSetId;
		}
		Message message = addUserActionSets(new UserActionSet(type, "小程序", "小程序"));
		if (message.getType().equals(Message.Type.success)) {
			return message.getExtra().toString();
		}
		return null;
	}

	@Override
	public Message findUserActionSetReports(String userActionSetId, Date startDate, Date endDate, TimeGranularity timeGranularity, Aggregation aggregation)
			throws HttpClientException, WeixinException {
		if (StringUtils.isBlank(userActionSetId)) {
			throw new YgException("用户行为源id不能为空");
		}
		UserActionApi api = new UserActionApi(WxMpAuthorityService.findTokenHolder());
		startDate = startDate != null ? startDate : new Date();
		endDate = endDate != null ? endDate : new Date();
		timeGranularity = timeGranularity != null ? timeGranularity : TimeGranularity.DAILY;
		aggregation = aggregation != null ? aggregation : Aggregation.ACTION_TYPE;
		JSONObject jsonObject = api.getUserActionSetReports(userActionSetId, startDate, endDate, timeGranularity, aggregation);
		Integer code = jsonObject == null ? -1 : jsonObject.getInteger("errcode");
		if (code != 0) {
			throw new WeixinException(jsonObject.getString("errmsg"));
		}
		JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("list");
		List<UserActionReport> list = JSONArray.parseArray(jsonArray.toJSONString(), UserActionReport.class);
		return Message.success(list);
	}

}